
# 添加任务依赖功能, 跨任务流依赖, 添加状态触发机制 ok
# 任务流完成后，会提示任务流完成，但是没有退出任务流线程

import threading
import time
import logging

class TaskScheduler:
    def __init__(self):
        self.condition = threading.Condition()
        self.ready = False
        self.task_flows = {}
        self.task_flow_events = {}
        self.global_task_dependencies = {}
        self.global_task_completion = {}
        self.trigger_conditions = {}
        self.trigger_thread = None
        self.trigger_interval_time = 1

    def set_trigger_interval_time(self, interval_time):
        self.trigger_interval_time = interval_time

    def wait_for_ready(self):
        with self.condition:
            while not self.ready:
                self.condition.wait()
            logging.debug("条件满足，开始执行任务流")

    def set_ready(self):
        with self.condition:
            self.ready = True
            self.condition.notify_all()

    def add_task_flow(self, task_flow_name, tasks, dependencies=None, trigger_condition=None):
        with self.condition:
            self.task_flows[task_flow_name] = tasks
            self.task_flow_events[task_flow_name] = threading.Event()
            self.trigger_conditions[task_flow_name] = trigger_condition
            for task in tasks:
                task_name = task.__name__
                self.global_task_dependencies[task_name] = dependencies.get(task_name, [])
                self.global_task_completion[task_name] = False
            logging.debug(f"任务流 {task_flow_name} 已添加")

    def remove_task_flow(self, task_flow_name):
        with self.condition:
            if task_flow_name in self.task_flows:
                del self.task_flows[task_flow_name]
                del self.task_flow_events[task_flow_name]
                del self.trigger_conditions[task_flow_name]
                for task in self.task_flows[task_flow_name]:
                    task_name = task.__name__
                    del self.global_task_dependencies[task_name]
                    del self.global_task_completion[task_name]
                logging.debug(f"任务流 {task_flow_name} 已删除")
            else:
                logging.debug(f"任务流 {task_flow_name} 不存在")

    def set_task_flow_ready(self, task_flow_name):
        self.task_flow_events[task_flow_name].set()
        logging.debug(f"任务流 {task_flow_name} 的条件已满足")

    def run_task_flow(self, task_flow_name):
        while True:
            self.task_flow_events[task_flow_name].wait()
            if not self.task_flows[task_flow_name]:
                logging.debug(f"任务流 {task_flow_name} 为空，等待新任务")
                self.task_flow_events[task_flow_name].clear()
                continue

            for task in self.task_flows[task_flow_name]:
                task_name = task.__name__
                if all(self.global_task_completion.get(dep, False) for dep in self.global_task_dependencies[task_name]):
                    task()
                    self.global_task_completion[task_name] = True
                    self.task_flows[task_flow_name].remove(task)
                    logging.info(f"任务 {task_name} 执行完成")
                else:
                    logging.debug(f"任务 {task_name} 的依赖任务未完成，等待中...")
                    continue

            #if all(self.global_task_completion[task.__name__] for task in self.task_flows[task_flow_name]):
            #    self.task_flow_events[task_flow_name].clear()

            if all(self.global_task_completion[task.__name__] for task in self.task_flows[task_flow_name]):
                # self.remove_task_flow(task_flow_name)
                self.task_flow_events[task_flow_name].clear()
                del self.task_flow_events[task_flow_name]
                del self.trigger_conditions[task_flow_name]
                logging.debug(f"任务流 {task_flow_name} 执行完成, 退出调度")
                break  # 任务流完成，退出循环


    def trigger_thread_func(self):
        while True:
            for task_flow_name, trigger_condition in self.trigger_conditions.items():
                if trigger_condition and trigger_condition():
                    self.set_task_flow_ready(task_flow_name)
            # time.sleep(1)  # 每秒检查一次触发条件
            time.sleep(self.trigger_interval_time )

    def start(self):
        # 创建并启动等待条件的线程
        waiting_thread = threading.Thread(target=self.wait_for_ready)
        waiting_thread.start()

        # 创建并启动每个任务流的线程
        task_flow_num = 0
        task_thread={}
        for task_flow_name, tasks in self.task_flows.items():
            task_flow_num = task_flow_num + 1
            task_thread[task_flow_num] = threading.Thread(target=self.run_task_flow, args=(task_flow_name,))
            task_thread[task_flow_num].start()

        # 创建并启动触发条件检查线程
        self.trigger_thread = threading.Thread(target=self.trigger_thread_func)
        self.trigger_thread.start()

        # 不再等待 waiting_thread，避免主线程阻塞
        # waiting_thread.join()
        # for i in range(1, task_flow_num+1):
        #     task_thread[task_flow_num].join()

# 定义一些示例任务
def task1():
    logging.info("task1 执行任务 1")

def task2():
    logging.info("task2 执行任务 2")

def task3():
    logging.info("task3 执行任务 3")

def task4():
    logging.info("task4 执行任务 4")

# 定义触发条件函数
def trigger_condition1():
    # 模拟触发条件
    return some_flag1

def trigger_condition2():
    # 模拟触发条件
    return some_flag2

# 使用示例
if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    # logging.basicConfig(level=logging.DEBUG)

    some_flag1 = False
    some_flag2 = False

    scheduler = TaskScheduler()

    # 添加任务流
    scheduler.add_task_flow("flow1", [task1, task2], dependencies={"task2": ["task1", "task3"]}, trigger_condition=trigger_condition1)
    scheduler.add_task_flow("flow2", [task3, task4], dependencies={"task4": ["task3"]}, trigger_condition=trigger_condition2)

    # 启动调度器
    scheduler.start()

    # 模拟条件变为 True
    time.sleep(2)  # 模拟等待时间
    scheduler.set_ready()

    # 动态设置触发条件
    time.sleep(2)
    some_flag1 = True

    time.sleep(2)
    some_flag2 = True

    # 等待一段时间，确保任务流执行完成
    time.sleep(10)